'''
<html>
<head></head>
<body>
	<h1>you</h1>
	<div>are</div>
	<p>haha<div>welcome</div>ye</p>
</body>
</html>
'''
from  sgmllib import SGMLParser,SGMLParseError 
import re
_delPat=re.compile('<!.+?>|<script.+?</script>|<style.+?</style>', \
				re.S|re.I)
def tidy_html(strHTML):
	return _delPat.sub('',strHTML)

#container tags,lower-cased 
ContainerTags=['div','table','tr','body','head','ul']
class Error:
	def __init__(self,str):
		self.str=str
	def __str__(self):
		return self.str
def depth_first_walk(node,func,arg):
		if node.tag=='text':
			func(node,arg,True)
		else:
			func(node,arg,True)
			for c in node.childs:
				depth_first_walk(c,func,arg)
			func(node,arg,False)
class Node:
	def __init__(self):
		self.tag=''
		self.parent=None
		self.childs=[]

	def __to_str(self,node,strs,first):
		if node.tag=='text':
			strs.append(node.content)
		else:
			if first:
				strs.append('<'+node.tag+'>')
			else:
				strs.append('</'+node.tag+'>')

	def to_str(self):
		strs=[]
		depth_first_walk(self,self.__to_str,strs)
		return ''.join(strs)
	def all_parents(self):
		ps=[]
		p=self.parent
		while p:
			ps.append(p)
			p=p.parent
		return ps	

class TextNode(Node):
	def __init__(self):
		Node.__init__(self)
		self.tag='text'
		self.content=''
		self.childs=None
class Doc(Node):
	def __init__(self):
		Node.__init__(self)
		self.tag='html'
	#def find_by_tag_name(self,tagName):
	#	l=[]
	#	return l

class DomBuilder(SGMLParser):
	def __init__(self):
		self.__doc=Doc()
		self.__curContainer=self.__doc
		self.__curNode=self.__curContainer
		SGMLParser.__init__(self)

	def parse(self,data):
		self.feed(data)
		return self.__doc
	def feed(self,data):
		data=tidy_html(data)
		SGMLParser.feed(self,data)
		self.close()

	def unknown_starttag(self,tag,attrs):
		if tag in ContainerTags:
			n=Node()
			n.tag=tag
			n.parent=self.__curContainer
			self.__curContainer.childs.append(n)
			self.__curContainer=n
			self.__curNode=n
			


	def handle_data(self,data):
		if self.__curNode.tag=='text':
			self.__curNode.content+=data
		else:
			n=TextNode()
			n.content=data
			n.parent=self.__curContainer
			self.__curContainer.childs.append(n)
			self.__curNode=n
	def unknown_endtag(self,tag):
		if tag in ContainerTags:
			cur=self.__curContainer
			if cur.tag!=tag:
				raise Error('unbalanced:</'+tag+'>')
			#back reverse
			self.__curContainer=cur.parent
			self.__curNode=cur.parent

